const express = require('express');
const fs = require('fs-extra');
const path = require('path');
const { VM } = require('vm2');
const axios = require('axios');

const router = express.Router();
const DATA_PATH = path.join(__dirname, '../data/routes.json');

function getAllRoutes() {
  return fs.readJsonSync(DATA_PATH, { throws: false }) || [];
}

function clearMockRoutes() {
  // 只移除动态mock路由，保留其他中间件
  router.stack = router.stack.filter(layer => {
    // 只保留不是mock路由的
    if (!layer.route) return true;
    const path = layer.route.path;
    // 只移除以/开头的mock路由（可根据实际情况调整）
    return false;
  });
}

async function runMockScript(route, input) {
  // 支持await callRoute、callRouteByPath、httpRequest
  const callRoute = async (id, params) => {
    const all = getAllRoutes();
    const target = all.find(r => r.id === id);
    if (!target) throw new Error('未找到被调用路由');
    return await runMockScript(target, params || {});
  };
  const callRouteByPath = async (method, path, params) => {
    const all = getAllRoutes();
    const target = all.find(r => r.method.toLowerCase() === method.toLowerCase() && r.path === path);
    if (!target) throw new Error('未找到指定方法和路径的mock路由');
    return await runMockScript(target, params || {});
  };
  const httpRequest = async (url, options = {}) => {
    const resp = await axios({ url, ...options });
    return resp.data;
  };
  const vm = new VM({
    sandbox: {
      request: input || {},
      query: {},
      callRoute,
      callRouteByPath,
      httpRequest
    },
    timeout: 3000
  });
  let result = vm.run(`(async () => { ${route.responseScript} })()`);
  if (result && typeof result.then === 'function') result = await result;
  return result;
}

function registerMockRoutes() {
  const routes = getAllRoutes();
  routes.forEach(route => {
    const method = route.method.toLowerCase();
    // 避免重复注册
    if (router.stack.some(layer => layer.route && layer.route.path === route.path && layer.route.methods[method])) return;
    router[method](route.path, async (req, res) => {
      try {
        if (route.delay) await new Promise(r => setTimeout(r, Number(route.delay)));
        const input = method === 'get' ? req.query : req.body;
        const result = await runMockScript(route, input);
        res.json(result);
      } catch (e) {
        res.status(500).json({ code: 500, msg: 'mock执行出错', error: String(e) });
      }
    });
  });
}

function reloadMockRoutes() {
  clearMockRoutes();
  registerMockRoutes();
}

// 启动时注册一次
registerMockRoutes();

module.exports = router;
module.exports.reloadMockRoutes = reloadMockRoutes; 